//echo服务器，保证服务器完整收到，回传服务器的包
#include <cstdlib>
#include <iostream>
#include <memory>
#include <utility>
#include <boost/asio.hpp>

using boost::asio::ip::tcp;

class session : public std::enable_shared_from_this<session> {
public:
	session(tcp::socket socket) : socket_(std::move(socket)) {}
	//被move之后，类处于未定义、初始化的状态
	void start(){ do_read(); }
private:
	void do_read() {
		auto self(shared_from_this());
		socket_.async_read_some(
			boost::asio::buffer(data_, max_length),
			[this, self](boost::system::error_code ec, std::size_t length){
				if(!ec) {
					do_write(length);
				}
			});//收到消息告知，此时退出self计数为1
	}
	void do_write(std::size_t length) {
		auto self(shared_from_this());
		boost::asio::async_write(
			socket_, boost::asio::buffer(data_, length),
			[this, self](boost::system::error_code ec, std::size_t /*length*/)  {
			if(!ec) {
				do_read();
			}
			});
	}//如果write出错，self计数由1->0
	tcp::socket socket_;
	enum { max_length = 1024};
	char data_[max_length];
};

class server {
public:
	server(boost::asio::io_service &io_service, short port)
	: acceptor_(io_service, tcp::endpoint(tcp::v4(), port)),
	  socket_(io_service){}
	//构造函数仅把资源构造好，不要做事情，需要做事情可以写一个工厂类
	void start() {
		do_accept();
	}
private:
	void do_accept() {
		acceptor_.async_accept(socket_, [this](auto ec){
			if(!ec) {
				//std::make_shared<session>(std::move(socket))->start();
				auto newSession = std::make_shared<session>(std::move(socket_));
				newSession->start();
			}		
			do_accept();
		});
	}
	tcp::acceptor acceptor_;
	tcp::socket socket_;
};
/*1.用try-catch包裹起来
 *2.io_service,程序与操作系统的桥梁
 *3.class server：监听连接处理
 *4.run();异步程序，驱动体
 */
int main(int argc, char *argv[]) {
	try{
		if(argc != 2) {
			std::cerr << "Usage: async_tcp_echo_server <port>\n";
			return 1;
		}

		boost::asio::io_service io_service;
		server s(io_service, std::atoi(argv[1]));
		s.start();
		io_service.run();
	}catch(std::exception &e) {
		std::cerr << "Exception: " << e.what() << "\n";
	}
	
	return 0;
}
